#include <stdio.h>
#include"config_1.h"
#include "sum.h"
#include "client_print.h"
//---------------------------------------------------------------------------//

int main(int argc,char**argv)
{   
    print_welcome();

    if(argc != 2){
        error(1,0,"lack of server.conf");
    }
    HashTable ht;
    initHashTable(&ht);
    readConfig(argv[1],&ht);
//---------------------------------------------------------------------------//
//网络连接部分
//connect_fd用于发送命令
//tsmfd用于传输文件
//在这里只进行connect_fd的连接
//tsmfd只在传输文件时连接，传输结束立即断开
    socklen_t len = sizeof(struct sockaddr);
    int err;
    //连接客户端
    
 
    printf(ANSI_COLOR_CYAN);
    printf("[System]");
    printf(ANSI_COLOR_RESET);
    printf("connecting server\n");

    struct sockaddr* addr = addr_create(find(&ht,IP_C),atoi((char*)find(&ht,PORT)));
    int connect_fd = socket(AF_INET,SOCK_STREAM,0);
    

    struct sockaddr* tsm_addr = addr_create(find(&ht,IP_C),atoi((char*)find(&ht,TSM_PORT)));
    int tsmfd;

    if(connect_fd == -1){
        error(1,errno,"socket");
    }


    err = connect(connect_fd,addr,len);
    if(err == -1){
        error(1,errno,"connect");
    }

    printf(ANSI_COLOR_CYAN);
    printf("[System]");
    printf(ANSI_COLOR_RESET);
    printf("connect finished\n");

    print_huanhang();
    print_usage();
//---------------------------------------------------------------------------//
    threadpool* thp;
    thp = threadpool_init(1);
    threadpool_start(thp,client_tsm_function,(void*)thp->q);
//---------------------------------------------------------------------------//
//初始化接收状态
//t_send只用于发送消息
//t_recv只用于接收消息
    char path[PATH_SIZE] = {'\0'};

    strcpy(path,"suis");

    cmd_tast t_send;
    

    strcpy(t_send.path,path);

    cmd_tast t_recv;
    int t_len = sizeof(cmd_tast);
    char buf[MAXCMDSIZE];

    int epfd = epoll_create1(0);
    epoll_mod(epfd,EPOLL_CTL_ADD,EPOLLIN,STDIN_FILENO);
    epoll_mod(epfd,EPOLL_CTL_ADD,EPOLLIN,connect_fd);

    struct epoll_event epev[2];
    int ep_num;
    while(1){
 
    printf(ANSI_COLOR_CYAN);
    printf("[System]");
    printf(ANSI_COLOR_RESET);
    printf("Input << 1 >>  Login\n");
  
    printf(ANSI_COLOR_CYAN);
    printf("[System]");
    printf(ANSI_COLOR_RESET);
  printf("Input << 2 >>  Registration\n");
        char c;
        c = getchar();
        getchar();
        if(c == '1'){
            login_01(&t_send,&connect_fd);
            login_02(&t_send,&connect_fd);
            strcpy(path,t_send.path);
            break;
        }
        if(c == '2'){
            client_regite1(connect_fd,&t_send); 
            client_regite2(connect_fd,&t_send); 
            strcpy(path,t_send.path);
            break;
        }
    }
    
    //由于后面要用到t_send，所有把jwt存到这里
    char jwt[256]= {0};
    strcpy(jwt,t_send.content);
   // printf("\n jwt:%s\n",t_send.content);
    memset(t_send.content,0,sizeof(t_send.content));
    
    
    printf(ANSI_COLOR_CYAN);
    printf("network_disk>> ");
    printf(ANSI_COLOR_RESET);
    fflush(stdout);

//---------------------------------------------------------------------------//
//开始运行
    while(1){
        ep_num = epoll_wait(epfd,epev,2,-1);
        for(int i = 0;i<ep_num;i++){
            int fd = epev[i].data.fd;
            if(fd == STDIN_FILENO){//发送消息
                memset(&t_send,0,MAXCMDSIZE);
                fgets(buf,MAXCMDSIZE,stdin);
                if(strcmp(buf,"\n") == 0){
    printf(ANSI_COLOR_CYAN);
                    printf("network_disk>> ");
    printf(ANSI_COLOR_RESET);
                    fflush(stdout);
                    break;  
                }
                make_cmd_tast(&t_send,buf);
                strcpy(t_send.path,path);
                send(connect_fd,(char*)&t_send,t_len,0);
            }else{//以下全是接收消息
                err = recv(connect_fd,(char*)&t_recv,t_len,0);
                if(err == -1){
                    error(0,errno,"recv");
                    continue;
                }else if(err == 0){
                    error(1,errno,"connect close");
                }
                //需要打印消息的回信
                if(t_recv.peerfd == 0){
                    printf("%s\n",t_recv.content);
                }
                //接收文件状态
                if(t_recv.cmdType == CMD_TYPE_DOWNLOAD || t_recv.cmdType == CMD_TYPE_UPLOAD || t_recv.cmdType == CMD_TYPE_DOWNLOAD_BG){
                    tsmfd = socket(AF_INET,SOCK_STREAM,0);  
                    err = connect(tsmfd,tsm_addr,len);                   
                    if(err == -1){
                        error(0,errno,"connect");
                        continue;
                    }
                    
                    //验证令牌不知道到底在子线程连接前，还是连接后,那就连接后吧  
                    //发送令牌到服务器
                    err=send(tsmfd,jwt,strlen(jwt),0);
                   // printf("send jwt:%d\n",err);

                    //接收验证结果
                    int verify;
                    recv(tsmfd,&verify,sizeof(verify),0);
                  //  printf("verify:%d\n",verify);
                   
                    if(verify==1){ 
    printf(ANSI_COLOR_CYAN);
    printf("network_disk>> ");
    printf(ANSI_COLOR_RESET);
                    printf("Baby ~ You have been verified\n");
                    cmd_tast* t_tsm = (cmd_tast*)malloc(sizeof(cmd_tast));
                    *t_tsm = t_recv;
                    t_tsm->peerfd = tsmfd;
                    tast_queue_push(thp->q,t_tsm);
                  }
                    else{
    printf(ANSI_COLOR_CYAN);
    printf("network_disk>> ");
    printf(ANSI_COLOR_RESET);
                        printf("OH~GOD~PLEASE~NO  You are not my baby !!!\n");
                    }
                }
                //更新path
                strcpy(path,t_recv.path);
    printf(ANSI_COLOR_CYAN);
                printf("network_disk>> ");
    printf(ANSI_COLOR_RESET);
                fflush(stdout);
            }
        }
    }
    return 0;

}

//---------------------------------------------------------------------------//
